package com.lefevre.cms.web.action.question;

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.util.concurrent.AtomicLongMap;
import com.lefevre.cms.bean.question.AppendQuestionItem;
import com.lefevre.cms.bean.question.Question;
import com.lefevre.cms.bean.question.QuestionTagAssociation;
import com.lefevre.cms.bean.setting.EditorTag;
import com.lefevre.cms.bean.staff.SysUsers;
import com.lefevre.cms.bean.user.User;
import com.lefevre.cms.service.question.AnswerService;
import com.lefevre.cms.service.question.QuestionService;
import com.lefevre.cms.service.staff.StaffService;
import com.lefevre.cms.service.user.UserService;
import com.lefevre.cms.utils.FileUtil;
import com.lefevre.cms.utils.JsonUtils;
import com.lefevre.cms.web.action.TextFilterManage;
import com.lefevre.cms.web.action.fileSystem.FileManage;
import com.lefevre.cms.web.action.setting.SettingManage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

/**
 * 问题管理
 */
@Component("questionManage")
public class QuestionManage {

    @Resource
    QuestionManage questionManage;
    @Resource
    TextFilterManage textFilterManage;
    @Resource
    QuestionService questionService;
    @Resource
    StaffService staffService;
    @Resource
    UserService userService;
    @Resource
    SettingManage settingManage;
    @Resource
    AnswerService answerService;
    @Resource
    FileManage fileManage;

    //key: 问题Id value:展示次数
    private AtomicLongMap<Long> countMap = AtomicLongMap.create();

    /**
     * 增加问题展示次数
     *
     * @param questionId 问题Id
     * @param ip
     */
    public void addView(Long questionId, String ip) {

        Long time = new Date().getTime();
        Long oldTime = questionManage.ipRecord(questionId + "_" + ip, time);
        if (oldTime != null && time.equals(oldTime)) {
            //增加
            countMap.incrementAndGet(questionId);
        }
    }

    /**
     * 提交问题展示次数到数据库(定时提交)
     */
    @Scheduled(fixedDelay = 600000)//10分钟
    public void commitCount() {
        //计数
        int i = 0;

        Map<Long, Long> batchCount = new HashMap<Long, Long>();

        for (Map.Entry<Long, Long> entry : countMap.asMap().entrySet()) {
            Long questionId = entry.getKey();
            Long count = entry.getValue();

            i++;
            if (count > 0L) {
                batchCount.put(questionId, count);
                countMap.addAndGet(questionId, count * -1L);//减少
            }
            if (i == 100) {//每100条提交一次到数据库
                if (batchCount.size() > 0) {
                    questionService.addViewCount(batchCount);
                    batchCount.clear();
                }
                i = 0;
            }
        }

        //将剩余的展示次数提交到数据库
        if (batchCount.size() > 0) {
            questionService.addViewCount(batchCount);
        }

        //删除所有计数器值为零的映射
        countMap.removeAllZeros();
    }


    /**
     * 话题展示IP记录(每话题每IP 24小时内只统计一次点击次数)
     *
     * @param key  话题Id_用户IP
     * @param time 当前时间
     * @return
     */
    @Cacheable(value = "questionManage_cache_ipRecord", key = "#key")
    public Long ipRecord(String key, Long time) {
        return time;
    }


    /**
     * 生成上传文件编号
     *
     * @param userName 用户名称
     * @param isStaff  是否是员工   true:员工   false:会员
     * @return
     */
    public String generateFileNumber(String userName, Boolean isStaff) {
        String number = "";

        if (isStaff != null && userName != null && !"".equals(userName.trim())) {
            if (isStaff) {//员工

                SysUsers sysUsers = staffService.findByUserAccount(userName.trim());
                if (sysUsers != null) {
                    number = "a" + sysUsers.getUserId();
                }
            } else {//会员
                User user = userService.findUserByUserName(userName.trim());
                if (user != null) {
                    number = "b" + user.getId();
                }
            }
        }
        return number;
    }

    /**
     * 根据文件名获取文件编号
     *
     * @param fileName 文件名称(不含后缀)
     * @return
     */
    public String getFileNumber(String fileName) {
        String number = "";

        if (fileName != null && !"".equals(fileName.trim())) {
            fileName = fileName.trim();
            if (fileName.length() > 33) {
                String isStaff = fileName.substring(32, 33);
                if (isStaff.equals("a") || isStaff.equals("b")) {
                    number = fileName.substring(32, fileName.length());
                }
            }
        }
        return number;
    }


    /**
     * 根据用户名称删除用户下的所有问题文件
     *
     * @param userName 用户名称
     * @param isStaff  是否为员工
     */
    public void deleteQuestionFile(String userName, boolean isStaff) {
        int firstIndex = 0;//起始页
        int maxResult = 100;// 每页显示记录数

        String fileNumber = questionManage.generateFileNumber(userName, isStaff);

        while (true) {
            List<Question> questionContentList = questionService.findQuestionContentByPage(firstIndex, maxResult, userName, isStaff);
            if (questionContentList == null || questionContentList.size() == 0) {
                break;
            }
            firstIndex = firstIndex + maxResult;
            for (Question question : questionContentList) {
                Long questionId = question.getId();
                String questionContent = question.getContent();


                //删除最后一个逗号
                String _appendContent = StringUtils.substringBeforeLast(question.getAppendContent(), ",");//从右往左截取到相等的字符,保留左边的

                List<AppendQuestionItem> appendQuestionItemList = JsonUtils.toGenericObject(_appendContent + "]", new TypeReference<List<AppendQuestionItem>>() {
                });
                if (appendQuestionItemList != null && appendQuestionItemList.size() > 0) {
                    for (AppendQuestionItem appendQuestionItem : appendQuestionItemList) {
                        questionContent += appendQuestionItem.getContent();
                    }
                }

                if (questionContent != null && !"".equals(questionContent.trim())) {
                    Object[] obj = textFilterManage.readPathName(questionContent, "question");

                    if (obj != null && obj.length > 0) {
                        List<String> filePathList = new ArrayList<>();


                        //删除图片
                        List<String> imageNameList = (List<String>) obj[0];
                        for (String imageName : imageNameList) {
                            filePathList.add(imageName);
                        }
                        //删除Flash
                        List<String> flashNameList = (List<String>) obj[1];
                        for (String flashName : flashNameList) {
                            filePathList.add(flashName);
                        }
                        //删除影音
                        List<String> mediaNameList = (List<String>) obj[2];
                        for (String mediaName : mediaNameList) {
                            filePathList.add(mediaName);
                        }
                        //删除文件
                        List<String> fileNameList = (List<String>) obj[3];
                        for (String fileName : fileNameList) {
                            filePathList.add(fileName);
                        }

                        for (String filePath : filePathList) {


                            //如果验证不是当前用户上传的文件，则不删除
                            if (!questionManage.getFileNumber(FileUtil.getBaseName(filePath.trim())).equals(fileNumber)) {
                                continue;
                            }

                            //替换路径中的..号
                            filePath = FileUtil.toRelativePath(filePath);
                            filePath = FileUtil.toSystemPath(filePath);
                            //删除旧路径文件
                            Boolean state = fileManage.deleteFile(filePath);
                            if (state != null && state == false) {
                                //替换指定的字符，只替换第一次出现的
                                filePath = StringUtils.replaceOnce(filePath, "file" + File.separator + "question" + File.separator, "");

                                //创建删除失败文件
                                fileManage.failedStateFile("file" + File.separator + "question" + File.separator + "lock" + File.separator + FileUtil.toUnderline(filePath));
                            }
                        }

                    }
                }
                //清空目录
                Boolean state_ = fileManage.removeDirectory("file" + File.separator + "answer" + File.separator + questionId + File.separator);
                if (state_ != null && state_ == false) {
                    //创建删除失败目录文件
                    fileManage.failedStateFile("file" + File.separator + "answer" + File.separator + "lock" + File.separator + "#" + questionId);
                }
            }

        }
    }


    /**
     * 根据用户名称删除用户下的所有答案文件
     *
     * @param userName 用户名称
     * @param isStaff  是否为员工
     */
    public void deleteAnswerFile(String userName, boolean isStaff) {
        int firstIndex = 0;//起始页
        int maxResult = 100;// 每页显示记录数

        String fileNumber = questionManage.generateFileNumber(userName, isStaff);

        while (true) {
            List<String> contentList = answerService.findAnswerContentByPage(firstIndex, maxResult, userName, isStaff);
            if (contentList == null || contentList.size() == 0) {
                break;
            }
            firstIndex = firstIndex + maxResult;
            for (String content : contentList) {
                if (content != null && !"".equals(content.trim())) {
                    //删除图片
                    List<String> imageNameList = textFilterManage.readImageName(content, "answer");
                    if (imageNameList != null && imageNameList.size() > 0) {
                        for (String imagePath : imageNameList) {
                            //如果验证不是当前用户上传的文件，则不删除锁
                            if (!questionManage.getFileNumber(FileUtil.getBaseName(imagePath.trim())).equals(fileNumber)) {
                                continue;
                            }


                            //替换路径中的..号
                            imagePath = FileUtil.toRelativePath(imagePath);

                            imagePath = FileUtil.toSystemPath(imagePath);

                            Boolean state = fileManage.deleteFile(imagePath);
                            if (state != null && state == false) {
                                //替换指定的字符，只替换第一次出现的
                                imagePath = StringUtils.replaceOnce(imagePath, "file" + File.separator + "answer" + File.separator, "");

                                //创建删除失败文件
                                fileManage.failedStateFile("file" + File.separator + "answer" + File.separator + "lock" + File.separator + FileUtil.toUnderline(imagePath));

                            }
                        }
                    }
                }
            }
        }
    }


    /**
     * 问题编辑器允许使用标签
     *
     * @return List<String> 类型json格式
     */
    public String availableTag() {
        List<String> tag = new ArrayList<>();
        EditorTag editor = settingManage.readQuestionEditorTag();
        if (editor != null) {
            //标签区域1
            boolean area_1 = false;
            //标签区域2
            boolean area_2 = false;
            //标签区域3
            boolean area_3 = false;

            tag.add("source");
            //	tag.add("|");
            if (editor.isCode()) {//代码
                tag.add("code");
                area_1 = true;
            }
            if (editor.isFontname()) {//字体
                tag.add("fontname");
                area_1 = true;
            }
            if (editor.isFontsize()) {//文字大小
                tag.add("fontsize");
                area_1 = true;
            }
            if (area_1) {
                //		tag.add("|");
            }

            if (editor.isForecolor()) {//文字颜色
                tag.add("forecolor");
                area_2 = true;
            }
            if (editor.isHilitecolor()) {//文字背景
                tag.add("hilitecolor");
                area_2 = true;
            }
            if (editor.isBold()) {//粗体
                tag.add("bold");
                area_2 = true;
            }
            if (editor.isItalic()) {//斜体
                tag.add("italic");
                area_2 = true;
            }
            if (editor.isUnderline()) {//下划线
                tag.add("underline");
                area_2 = true;
            }
            if (editor.isRemoveformat()) {//删除格式
                tag.add("removeformat");
                area_2 = true;
            }
            if (editor.isLink()) {//超级链接
                tag.add("link");
                area_2 = true;
            }
            if (editor.isUnlink()) {//取消超级链接
                tag.add("unlink");
                area_2 = true;
            }
            if (area_2) {
                //	tag.add("|");
            }

            if (editor.isJustifyleft()) {//左对齐
                tag.add("justifyleft");
                area_3 = true;
            }
            if (editor.isJustifycenter()) {//居中
                tag.add("justifycenter");
                area_3 = true;
            }
            if (editor.isJustifyright()) {//右对齐
                tag.add("justifyright");
                area_3 = true;
            }
            if (editor.isInsertorderedlist()) {//编号
                tag.add("insertorderedlist");
                area_3 = true;
            }
            if (editor.isInsertunorderedlist()) {//项目符号
                tag.add("insertunorderedlist");
                area_3 = true;
            }
            if (area_3) {
                //	tag.add("|");
            }

            if (editor.isEmoticons()) {//插入表情
                tag.add("emoticons");
            }
            if (editor.isImage()) {//图片
                tag.add("image");
            }
            /**
             if(editor.isFile()){//文件
             tag.add("insertfile");
             }**/
            if (editor.isFullscreen()) {//全屏显示
                tag.add("fullscreen");
            }
        }
        return JsonUtils.toJSONString(tag);
    }


    /**
     * 查询缓存 根据Id查询问题
     *
     * @param questionId 问题Id
     * @return
     */
    @Cacheable(value = "questionManage_cache_findById", key = "#questionId")
    public Question query_cache_findById(Long questionId) {
        return questionService.findById(questionId);
    }

    /**
     * 删除缓存 根据Id查询问题
     *
     * @param questionId 问题Id
     * @return
     */
    @CacheEvict(value = "questionManage_cache_findById", key = "#questionId")
    public void delete_cache_findById(Long questionId) {
    }

    /**
     * 查询缓存 根据问题Id查询问题标签关联
     *
     * @param questionId 问题Id
     * @return
     */
    @Cacheable(value = "questionManage_cache_findQuestionTagAssociationByQuestionId", key = "#questionId")
    public List<QuestionTagAssociation> query_cache_findQuestionTagAssociationByQuestionId(Long questionId) {
        return questionService.findQuestionTagAssociationByQuestionId(questionId);
    }

    /**
     * 删除缓存 根据问题Id查询问题标签关联
     *
     * @param questionId 问题Id
     * @return
     */
    @CacheEvict(value = "questionManage_cache_findQuestionTagAssociationByQuestionId", key = "#questionId")
    public void delete_cache_findQuestionTagAssociationByQuestionId(Long questionId) {
    }


}
